home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / mail / sendmail / sendmail-5.65c+IDA-1.4.4.1 / src / RCS / srvrsmtp.c,v < prev    next >
Encoding:
Text File  |  1991-06-25  |  23.3 KB  |  1,221 lines

  1. head    5.28;
  2. branch    5.28.0;
  3. access;
  4. symbols
  5.     RELEASE:5.28.0.15
  6.     BETA:5.28.0.15
  7.     UICSO:5.28.0
  8.     VANILLA:5.28;
  9. locks; strict;
  10. comment    @ * @;
  11.  
  12.  
  13. 5.28
  14. date    90.06.20.08.36.34;    author paul;    state Exp;
  15. branches
  16.     5.28.0.1;
  17. next    ;
  18.  
  19. 5.28.0.1
  20. date    90.06.20.09.44.03;    author paul;    state Exp;
  21. branches;
  22. next    5.28.0.2;
  23.  
  24. 5.28.0.2
  25. date    90.10.13.19.14.17;    author paul;    state Exp;
  26. branches;
  27. next    5.28.0.3;
  28.  
  29. 5.28.0.3
  30. date    90.10.25.20.18.09;    author paul;    state Exp;
  31. branches;
  32. next    5.28.0.4;
  33.  
  34. 5.28.0.4
  35. date    90.11.02.00.19.43;    author paul;    state Exp;
  36. branches;
  37. next    5.28.0.5;
  38.  
  39. 5.28.0.5
  40. date    90.11.26.20.38.16;    author paul;    state Exp;
  41. branches;
  42. next    5.28.0.6;
  43.  
  44. 5.28.0.6
  45. date    91.01.19.19.26.02;    author paul;    state Exp;
  46. branches;
  47. next    5.28.0.7;
  48.  
  49. 5.28.0.7
  50. date    91.02.17.05.23.36;    author paul;    state Exp;
  51. branches;
  52. next    5.28.0.8;
  53.  
  54. 5.28.0.8
  55. date    91.03.04.21.48.23;    author paul;    state Exp;
  56. branches;
  57. next    5.28.0.9;
  58.  
  59. 5.28.0.9
  60. date    91.03.16.17.35.28;    author paul;    state Exp;
  61. branches;
  62. next    5.28.0.10;
  63.  
  64. 5.28.0.10
  65. date    91.04.02.23.22.52;    author paul;    state Exp;
  66. branches;
  67. next    5.28.0.11;
  68.  
  69. 5.28.0.11
  70. date    91.04.05.14.55.15;    author paul;    state Exp;
  71. branches;
  72. next    5.28.0.12;
  73.  
  74. 5.28.0.12
  75. date    91.05.18.18.23.54;    author paul;    state Exp;
  76. branches;
  77. next    5.28.0.13;
  78.  
  79. 5.28.0.13
  80. date    91.06.06.19.50.49;    author paul;    state Exp;
  81. branches;
  82. next    5.28.0.14;
  83.  
  84. 5.28.0.14
  85. date    91.06.13.20.18.34;    author paul;    state Exp;
  86. branches;
  87. next    5.28.0.15;
  88.  
  89. 5.28.0.15
  90. date    91.06.24.20.27.06;    author paul;    state Exp;
  91. branches;
  92. next    ;
  93.  
  94.  
  95. desc
  96. @@
  97.  
  98.  
  99. 5.28
  100. log
  101. @5.64 Berkeley release
  102. @
  103. text
  104. @/*
  105.  * Copyright (c) 1983 Eric P. Allman
  106.  * Copyright (c) 1988 Regents of the University of California.
  107.  * All rights reserved.
  108.  *
  109.  * Redistribution and use in source and binary forms are permitted provided
  110.  * that: (1) source distributions retain this entire copyright notice and
  111.  * comment, and (2) distributions including binaries display the following
  112.  * acknowledgement:  ``This product includes software developed by the
  113.  * University of California, Berkeley and its contributors'' in the
  114.  * documentation or other materials provided with the distribution and in
  115.  * all advertising materials mentioning features or use of this software.
  116.  * Neither the name of the University nor the names of its contributors may
  117.  * be used to endorse or promote products derived from this software without
  118.  * specific prior written permission.
  119.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
  120.  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
  121.  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  122.  */
  123.  
  124. # include "sendmail.h"
  125.  
  126. #ifndef lint
  127. #ifdef SMTP
  128. static char sccsid[] = "@@(#)srvrsmtp.c    5.28 (Berkeley) 6/1/90 (with SMTP)";
  129. #else
  130. static char sccsid[] = "@@(#)srvrsmtp.c    5.28 (Berkeley) 6/1/90 (without SMTP)";
  131. #endif
  132. #endif /* not lint */
  133.  
  134. # include <errno.h>
  135. # include <signal.h>
  136.  
  137. # ifdef SMTP
  138.  
  139. /*
  140. **  SMTP -- run the SMTP protocol.
  141. **
  142. **    Parameters:
  143. **        none.
  144. **
  145. **    Returns:
  146. **        never.
  147. **
  148. **    Side Effects:
  149. **        Reads commands from the input channel and processes
  150. **            them.
  151. */
  152.  
  153. struct cmd
  154. {
  155.     char    *cmdname;    /* command name */
  156.     int    cmdcode;    /* internal code, see below */
  157. };
  158.  
  159. /* values for cmdcode */
  160. # define CMDERROR    0    /* bad command */
  161. # define CMDMAIL    1    /* mail -- designate sender */
  162. # define CMDRCPT    2    /* rcpt -- designate recipient */
  163. # define CMDDATA    3    /* data -- send message text */
  164. # define CMDRSET    4    /* rset -- reset state */
  165. # define CMDVRFY    5    /* vrfy -- verify address */
  166. # define CMDHELP    6    /* help -- give usage info */
  167. # define CMDNOOP    7    /* noop -- do nothing */
  168. # define CMDQUIT    8    /* quit -- close connection and die */
  169. # define CMDHELO    9    /* helo -- be polite */
  170. # define CMDONEX    10    /* onex -- sending one transaction only */
  171. # define CMDVERB    11    /* verb -- go into verbose mode */
  172. /* debugging-only commands, only enabled if SMTPDEBUG is defined */
  173. # define CMDDBGQSHOW    12    /* showq -- show send queue */
  174. # define CMDDBGDEBUG    13    /* debug -- set debug mode */
  175.  
  176. static struct cmd    CmdTab[] =
  177. {
  178.     "mail",        CMDMAIL,
  179.     "rcpt",        CMDRCPT,
  180.     "data",        CMDDATA,
  181.     "rset",        CMDRSET,
  182.     "vrfy",        CMDVRFY,
  183.     "expn",        CMDVRFY,
  184.     "help",        CMDHELP,
  185.     "noop",        CMDNOOP,
  186.     "quit",        CMDQUIT,
  187.     "helo",        CMDHELO,
  188.     "verb",        CMDVERB,
  189.     "onex",        CMDONEX,
  190.     /*
  191.      * remaining commands are here only
  192.      * to trap and log attempts to use them
  193.      */
  194.     "showq",    CMDDBGQSHOW,
  195.     "debug",    CMDDBGDEBUG,
  196.     NULL,        CMDERROR,
  197. };
  198.  
  199. bool    InChild = FALSE;        /* true if running in a subprocess */
  200. bool    OneXact = FALSE;        /* one xaction only this run */
  201.  
  202. #define EX_QUIT        22        /* special code for QUIT command */
  203.  
  204. smtp()
  205. {
  206.     register char *p;
  207.     register struct cmd *c;
  208.     char *cmd;
  209.     extern char *skipword();
  210.     bool hasmail;            /* mail command received */
  211.     auto ADDRESS *vrfyqueue;
  212.     ADDRESS *a;
  213.     char *sendinghost;
  214.     char inp[MAXLINE];
  215.     char cmdbuf[100];
  216.     extern char Version[];
  217.     extern char *macvalue();
  218.     extern ADDRESS *recipient();
  219.     extern ENVELOPE BlankEnvelope;
  220.     extern ENVELOPE *newenvelope();
  221.  
  222.     hasmail = FALSE;
  223.     if (OutChannel != stdout)
  224.     {
  225.         /* arrange for debugging output to go to remote host */
  226.         (void) close(1);
  227.         (void) dup(fileno(OutChannel));
  228.     }
  229.     settime();
  230.     if (RealHostName != NULL)
  231.     {
  232.         CurHostName = RealHostName;
  233.         setproctitle("srvrsmtp %s", CurHostName);
  234.     }
  235.     else
  236.     {
  237.         /* this must be us!! */
  238.         CurHostName = MyHostName;
  239.     }
  240.     expand("\001e", inp, &inp[sizeof inp], CurEnv);
  241.     message("220", inp);
  242.     SmtpPhase = "startup";
  243.     sendinghost = NULL;
  244.     for (;;)
  245.     {
  246.         /* arrange for backout */
  247.         if (setjmp(TopFrame) > 0 && InChild)
  248.             finis();
  249.         QuickAbort = FALSE;
  250.         HoldErrs = FALSE;
  251.  
  252.         /* setup for the read */
  253.         CurEnv->e_to = NULL;
  254.         Errors = 0;
  255.         (void) fflush(stdout);
  256.  
  257.         /* read the input line */
  258.         p = sfgets(inp, sizeof inp, InChannel);
  259.  
  260.         /* handle errors */
  261.         if (p == NULL)
  262.         {
  263.             /* end of file, just die */
  264.             message("421", "%s Lost input channel from %s",
  265.                 MyHostName, CurHostName);
  266.             finis();
  267.         }
  268.  
  269.         /* clean up end of line */
  270.         fixcrlf(inp, TRUE);
  271.  
  272.         /* echo command to transcript */
  273.         if (CurEnv->e_xfp != NULL)
  274.             fprintf(CurEnv->e_xfp, "<<< %s\n", inp);
  275.  
  276.         /* break off command */
  277.         for (p = inp; isspace(*p); p++)
  278.             continue;
  279.         cmd = p;
  280.         for (cmd = cmdbuf; *p != '\0' && !isspace(*p); )
  281.             *cmd++ = *p++;
  282.         *cmd = '\0';
  283.  
  284.         /* throw away leading whitespace */
  285.         while (isspace(*p))
  286.             p++;
  287.  
  288.         /* decode command */
  289.         for (c = CmdTab; c->cmdname != NULL; c++)
  290.         {
  291.             if (!strcasecmp(c->cmdname, cmdbuf))
  292.                 break;
  293.         }
  294.  
  295.         /* process command */
  296.         switch (c->cmdcode)
  297.         {
  298.           case CMDHELO:        /* hello -- introduce yourself */
  299.             SmtpPhase = "HELO";
  300.             setproctitle("%s: %s", CurHostName, inp);
  301.             if (!strcasecmp(p, MyHostName))
  302.             {
  303.                 /*
  304.                  * didn't know about alias,
  305.                  * or connected to an echo server
  306.                  */
  307.                 message("553", "Local configuration error, hostname not recognized as local");
  308.                 break;
  309.             }
  310.             if (RealHostName != NULL && strcasecmp(p, RealHostName))
  311.             {
  312.                 char hostbuf[MAXNAME];
  313.  
  314.                 (void) sprintf(hostbuf, "%s (%s)", p, RealHostName);
  315.                 sendinghost = newstr(hostbuf);
  316.             }
  317.             else
  318.                 sendinghost = newstr(p);
  319.             message("250", "%s Hello %s, pleased to meet you",
  320.                 MyHostName, sendinghost);
  321.             break;
  322.  
  323.           case CMDMAIL:        /* mail -- designate sender */
  324.             SmtpPhase = "MAIL";
  325.  
  326.             /* force a sending host even if no HELO given */
  327.             if (RealHostName != NULL && macvalue('s', CurEnv) == NULL)
  328.                 sendinghost = RealHostName;
  329.  
  330.             /* check for validity of this command */
  331.             if (hasmail)
  332.             {
  333.                 message("503", "Sender already specified");
  334.                 break;
  335.             }
  336.             if (InChild)
  337.             {
  338.                 errno = 0;
  339.                 syserr("Nested MAIL command");
  340.                 exit(0);
  341.             }
  342.  
  343.             /* fork a subprocess to process this command */
  344.             if (runinchild("SMTP-MAIL") > 0)
  345.                 break;
  346.             define('s', sendinghost, CurEnv);
  347.             define('r', "SMTP", CurEnv);
  348.             initsys();
  349.             setproctitle("%s %s: %s", CurEnv->e_id,
  350.                 CurHostName, inp);
  351.  
  352.             /* child -- go do the processing */
  353.             p = skipword(p, "from");
  354.             if (p == NULL)
  355.                 break;
  356.             setsender(p);
  357.             if (Errors == 0)
  358.             {
  359.                 message("250", "Sender ok");
  360.                 hasmail = TRUE;
  361.             }
  362.             else if (InChild)
  363.                 finis();
  364.             break;
  365.  
  366.           case CMDRCPT:        /* rcpt -- designate recipient */
  367.             SmtpPhase = "RCPT";
  368.             setproctitle("%s %s: %s", CurEnv->e_id,
  369.                 CurHostName, inp);
  370.             if (setjmp(TopFrame) > 0)
  371.             {
  372.                 CurEnv->e_flags &= ~EF_FATALERRS;
  373.                 break;
  374.             }
  375.             QuickAbort = TRUE;
  376.             p = skipword(p, "to");
  377.             if (p == NULL)
  378.                 break;
  379.             a = parseaddr(p, (ADDRESS *) NULL, 1, '\0');
  380.             if (a == NULL)
  381.                 break;
  382.             a->q_flags |= QPRIMARY;
  383.             a = recipient(a, &CurEnv->e_sendqueue);
  384.             if (Errors != 0)
  385.                 break;
  386.  
  387.             /* no errors during parsing, but might be a duplicate */
  388.             CurEnv->e_to = p;
  389.             if (!bitset(QBADADDR, a->q_flags))
  390.                 message("250", "Recipient ok");
  391.             else
  392.             {
  393.                 /* punt -- should keep message in ADDRESS.... */
  394.                 message("550", "Addressee unknown");
  395.             }
  396.             CurEnv->e_to = NULL;
  397.             break;
  398.  
  399.           case CMDDATA:        /* data -- text of mail */
  400.             SmtpPhase = "DATA";
  401.             if (!hasmail)
  402.             {
  403.                 message("503", "Need MAIL command");
  404.                 break;
  405.             }
  406.             else if (CurEnv->e_nrcpts <= 0)
  407.             {
  408.                 message("503", "Need RCPT (recipient)");
  409.                 break;
  410.             }
  411.  
  412.             /* collect the text of the message */
  413.             SmtpPhase = "collect";
  414.             setproctitle("%s %s: %s", CurEnv->e_id,
  415.                 CurHostName, inp);
  416.             collect(TRUE);
  417.             if (Errors != 0)
  418.                 break;
  419.  
  420.             /*
  421.             **  Arrange to send to everyone.
  422.             **    If sending to multiple people, mail back
  423.             **        errors rather than reporting directly.
  424.             **    In any case, don't mail back errors for
  425.             **        anything that has happened up to
  426.             **        now (the other end will do this).
  427.             **    Truncate our transcript -- the mail has gotten
  428.             **        to us successfully, and if we have
  429.             **        to mail this back, it will be easier
  430.             **        on the reader.
  431.             **    Then send to everyone.
  432.             **    Finally give a reply code.  If an error has
  433.             **        already been given, don't mail a
  434.             **        message back.
  435.             **    We goose error returns by clearing error bit.
  436.             */
  437.  
  438.             SmtpPhase = "delivery";
  439.             if (CurEnv->e_nrcpts != 1)
  440.             {
  441.                 HoldErrs = TRUE;
  442.                 ErrorMode = EM_MAIL;
  443.             }
  444.             CurEnv->e_flags &= ~EF_FATALERRS;
  445.             CurEnv->e_xfp = freopen(queuename(CurEnv, 'x'), "w", CurEnv->e_xfp);
  446.  
  447.             /* send to all recipients */
  448.             sendall(CurEnv, SM_DEFAULT);
  449.             CurEnv->e_to = NULL;
  450.  
  451.             /* save statistics */
  452.             markstats(CurEnv, (ADDRESS *) NULL);
  453.  
  454.             /* issue success if appropriate and reset */
  455.             if (Errors == 0 || HoldErrs)
  456.                 message("250", "Ok");
  457.             else
  458.                 CurEnv->e_flags &= ~EF_FATALERRS;
  459.  
  460.             /* if in a child, pop back to our parent */
  461.             if (InChild)
  462.                 finis();
  463.  
  464.             /* clean up a bit */
  465.             hasmail = 0;
  466.             dropenvelope(CurEnv);
  467.             CurEnv = newenvelope(CurEnv);
  468.             CurEnv->e_flags = BlankEnvelope.e_flags;
  469.             break;
  470.  
  471.           case CMDRSET:        /* rset -- reset state */
  472.             message("250", "Reset state");
  473.             if (InChild)
  474.                 finis();
  475.             break;
  476.  
  477.           case CMDVRFY:        /* vrfy -- verify address */
  478.             if (runinchild("SMTP-VRFY") > 0)
  479.                 break;
  480.             setproctitle("%s: %s", CurHostName, inp);
  481.             vrfyqueue = NULL;
  482.             QuickAbort = TRUE;
  483.             sendtolist(p, (ADDRESS *) NULL, &vrfyqueue);
  484.             if (Errors != 0)
  485.             {
  486.                 if (InChild)
  487.                     finis();
  488.                 break;
  489.             }
  490.             while (vrfyqueue != NULL)
  491.             {
  492.                 register ADDRESS *a = vrfyqueue->q_next;
  493.                 char *code;
  494.  
  495.                 while (a != NULL && bitset(QDONTSEND|QBADADDR, a->q_flags))
  496.                     a = a->q_next;
  497.  
  498.                 if (!bitset(QDONTSEND|QBADADDR, vrfyqueue->q_flags))
  499.                 {
  500.                     if (a != NULL)
  501.                         code = "250-";
  502.                     else
  503.                         code = "250";
  504.                     if (vrfyqueue->q_fullname == NULL)
  505.                         message(code, "<%s>", vrfyqueue->q_paddr);
  506.                     else
  507.                         message(code, "%s <%s>",
  508.                             vrfyqueue->q_fullname, vrfyqueue->q_paddr);
  509.                 }
  510.                 else if (a == NULL)
  511.                     message("554", "Self destructive alias loop");
  512.                 vrfyqueue = a;
  513.             }
  514.             if (InChild)
  515.                 finis();
  516.             break;
  517.  
  518.           case CMDHELP:        /* help -- give user info */
  519.             if (*p == '\0')
  520.                 p = "SMTP";
  521.             help(p);
  522.             break;
  523.  
  524.           case CMDNOOP:        /* noop -- do nothing */
  525.             message("200", "OK");
  526.             break;
  527.  
  528.           case CMDQUIT:        /* quit -- leave mail */
  529.             message("221", "%s closing connection", MyHostName);
  530.             if (InChild)
  531.                 ExitStat = EX_QUIT;
  532.             finis();
  533.  
  534.           case CMDVERB:        /* set verbose mode */
  535.             Verbose = TRUE;
  536.             SendMode = SM_DELIVER;
  537.             message("200", "Verbose mode");
  538.             break;
  539.  
  540.           case CMDONEX:        /* doing one transaction only */
  541.             OneXact = TRUE;
  542.             message("200", "Only one transaction");
  543.             break;
  544.  
  545. # ifdef SMTPDEBUG
  546.           case CMDDBGQSHOW:    /* show queues */
  547.             printf("Send Queue=");
  548.             printaddr(CurEnv->e_sendqueue, TRUE);
  549.             break;
  550.  
  551.           case CMDDBGDEBUG:    /* set debug mode */
  552.             tTsetup(tTdvect, sizeof tTdvect, "0-99.1");
  553.             tTflag(p);
  554.             message("200", "Debug set");
  555.             break;
  556.  
  557. # else /* not SMTPDEBUG */
  558.  
  559.           case CMDDBGQSHOW:    /* show queues */
  560.           case CMDDBGDEBUG:    /* set debug mode */
  561. # ifdef LOG
  562.             if (RealHostName != NULL && LogLevel > 0)
  563.                 syslog(LOG_NOTICE,
  564.                     "\"%s\" command from %s (%s)\n",
  565.                     c->cmdname, RealHostName,
  566.                     inet_ntoa(RealHostAddr.sin_addr));
  567. # endif
  568.             /* FALL THROUGH */
  569. # endif /* SMTPDEBUG */
  570.  
  571.           case CMDERROR:    /* unknown command */
  572.             message("500", "Command unrecognized");
  573.             break;
  574.  
  575.           default:
  576.             errno = 0;
  577.             syserr("smtp: unknown code %d", c->cmdcode);
  578.             break;
  579.         }
  580.     }
  581. }
  582. /*
  583. **  SKIPWORD -- skip a fixed word.
  584. **
  585. **    Parameters:
  586. **        p -- place to start looking.
  587. **        w -- word to skip.
  588. **
  589. **    Returns:
  590. **        p following w.
  591. **        NULL on error.
  592. **
  593. **    Side Effects:
  594. **        clobbers the p data area.
  595. */
  596.  
  597. static char *
  598. skipword(p, w)
  599.     register char *p;
  600.     char *w;
  601. {
  602.     register char *q;
  603.  
  604.     /* find beginning of word */
  605.     while (isspace(*p))
  606.         p++;
  607.     q = p;
  608.  
  609.     /* find end of word */
  610.     while (*p != '\0' && *p != ':' && !isspace(*p))
  611.         p++;
  612.     while (isspace(*p))
  613.         *p++ = '\0';
  614.     if (*p != ':')
  615.     {
  616.       syntax:
  617.         message("501", "Syntax error");
  618.         Errors++;
  619.         return (NULL);
  620.     }
  621.     *p++ = '\0';
  622.     while (isspace(*p))
  623.         p++;
  624.  
  625.     /* see if the input word matches desired word */
  626.     if (strcasecmp(q, w))
  627.         goto syntax;
  628.  
  629.     return (p);
  630. }
  631. /*
  632. **  HELP -- implement the HELP command.
  633. **
  634. **    Parameters:
  635. **        topic -- the topic we want help for.
  636. **
  637. **    Returns:
  638. **        none.
  639. **
  640. **    Side Effects:
  641. **        outputs the help file to message output.
  642. */
  643.  
  644. help(topic)
  645.     char *topic;
  646. {
  647.     register FILE *hf;
  648.     int len;
  649.     char buf[MAXLINE];
  650.     bool noinfo;
  651.  
  652.     if (HelpFile == NULL || (hf = fopen(HelpFile, "r")) == NULL)
  653.     {
  654.         /* no help */
  655.         errno = 0;
  656.         message("502", "HELP not implemented");
  657.         return;
  658.     }
  659.  
  660.     len = strlen(topic);
  661.     makelower(topic);
  662.     noinfo = TRUE;
  663.  
  664.     while (fgets(buf, sizeof buf, hf) != NULL)
  665.     {
  666.         if (strncmp(buf, topic, len) == 0)
  667.         {
  668.             register char *p;
  669.  
  670.             p = index(buf, '\t');
  671.             if (p == NULL)
  672.                 p = buf;
  673.             else
  674.                 p++;
  675.             fixcrlf(p, TRUE);
  676.             message("214-", p);
  677.             noinfo = FALSE;
  678.         }
  679.     }
  680.  
  681.     if (noinfo)
  682.         message("504", "HELP topic unknown");
  683.     else
  684.         message("214", "End of HELP info");
  685.     (void) fclose(hf);
  686. }
  687. /*
  688. **  RUNINCHILD -- return twice -- once in the child, then in the parent again
  689. **
  690. **    Parameters:
  691. **        label -- a string used in error messages
  692. **
  693. **    Returns:
  694. **        zero in the child
  695. **        one in the parent
  696. **
  697. **    Side Effects:
  698. **        none.
  699. */
  700.  
  701. runinchild(label)
  702.     char *label;
  703. {
  704.     int childpid;
  705.  
  706.     if (!OneXact)
  707.     {
  708.         childpid = dofork();
  709.         if (childpid < 0)
  710.         {
  711.             syserr("%s: cannot fork", label);
  712.             return (1);
  713.         }
  714.         if (childpid > 0)
  715.         {
  716.             auto int st;
  717.  
  718.             /* parent -- wait for child to complete */
  719.             st = waitfor(childpid);
  720.             if (st == -1)
  721.                 syserr("%s: lost child", label);
  722.  
  723.             /* if we exited on a QUIT command, complete the process */
  724.             if (st == (EX_QUIT << 8))
  725.                 finis();
  726.  
  727.             return (1);
  728.         }
  729.         else
  730.         {
  731.             /* child */
  732.             InChild = TRUE;
  733.             QuickAbort = FALSE;
  734.             clearenvelope(CurEnv, FALSE);
  735.         }
  736.     }
  737.  
  738.     /* open alias database */
  739.     initaliases(AliasFile, FALSE);
  740.  
  741.     return (0);
  742. }
  743.  
  744. # endif SMTP
  745. @
  746.  
  747.  
  748. 5.28.0.1
  749. log
  750. @IDA patches
  751. @
  752. text
  753. @a68 1
  754. # define CMDTICK    12    /* tick -- batch SMTP sync command */
  755. d70 2
  756. a71 2
  757. # define CMDDBGQSHOW    13    /* showq -- show send queue */
  758. # define CMDDBGDEBUG    14    /* debug -- set debug mode */
  759. a86 1
  760.     "tick",        CMDTICK,
  761. d101 1
  762. a101 2
  763. smtp(batched)
  764.     bool batched;            /* running non-interactively? */
  765. a103 1
  766.     int la;
  767. a111 1
  768.     char TickArg[20];
  769. a113 1
  770.     char hostbuf[MAXNAME];        /* for host name transformations */
  771. a136 7
  772.  
  773.     /* see if we are rejecting connections (see daemon.c) */
  774.     la = getla();
  775.     if (batched && la > RefuseLA) {
  776.         message("421", "%s too busy, try again later", MyHostName);
  777.         exit (EX_TEMPFAIL);
  778.     }
  779. d198 1
  780. a198 5
  781.  
  782.             /* find canonical name */
  783.             strcpy(hostbuf, p);
  784.             maphostname(hostbuf, sizeof(hostbuf));
  785.             if (!strcasecmp(hostbuf, MyHostName))
  786. d207 1
  787. a207 1
  788.             if (RealHostName != NULL && strcasecmp(hostbuf, RealHostName))
  789. d209 2
  790. a212 2
  791.                 message("250", "Hello %s, why do you call yourself %s?",
  792.                     RealHostName, p);
  793. a214 1
  794.             {
  795. d216 2
  796. a217 2
  797.                 message("250", "Hello %s, pleased to meet you", p);
  798.             }
  799. a242 1
  800.             define('r', "SMTP", CurEnv);
  801. d269 1
  802. a269 2
  803.                 if (!batched)
  804.                     CurEnv->e_flags &= ~EF_FATALERRS;
  805. d300 1
  806. a300 4
  807.                 message("503", "Need valid MAIL command");
  808.                 if (batched)
  809.                     Errors++;
  810.                 else
  811. d305 1
  812. a305 4
  813.                 message("503", "Need valid RCPT (recipient)");
  814.                 if (batched)
  815.                     Errors++;
  816.                 else
  817. d336 1
  818. a336 1
  819.             if (CurEnv->e_nrcpts != 1 || batched)
  820. d341 2
  821. a342 5
  822.             if (!batched) {
  823.                 CurEnv->e_flags &= ~EF_FATALERRS;
  824.                 CurEnv->e_xfp = freopen(queuename(CurEnv, 'x'),
  825.                             "w", CurEnv->e_xfp);
  826.             }
  827. a441 5
  828.           case CMDTICK:        /* BSMTP TICK */
  829.             (void) strncpy(TickArg, p, 20-1);
  830.             message("250", "OK");
  831.             break;
  832.  
  833. d636 1
  834. a636 1
  835.     initaliases(FALSE);
  836. @
  837.  
  838.  
  839. 5.28.0.2
  840. log
  841. @Fixed skipword() declaration.  Moved #include "sendmail" to avoid SIGCLD
  842. re-declaration warning when #define SYSTEM5 is set in conf.h.  Fixed 
  843. fencepost bug in third expand() argument.
  844. @
  845. text
  846. @d21 1
  847. a21 3
  848. #include <errno.h>
  849. #include <signal.h>
  850. #include "sendmail.h"
  851. d31 3
  852. d110 1
  853. a110 1
  854.     static char *skipword();
  855. d150 1
  856. a150 1
  857.     expand("\001e", inp, &inp[(sizeof(inp) - 1)], CurEnv);
  858. a503 1
  859.             syslog(LOG_NOTICE, "\"%s\" command unrecognized\n", cmdbuf);
  860. @
  861.  
  862.  
  863. 5.28.0.3
  864. log
  865. @Added missing #ifdef LOG, #endif around syslog() call.
  866. @
  867. text
  868. @d26 1
  869. a26 1
  870. # ifdef SMTP
  871. d28 1
  872. a28 1
  873. # else /* !SMTP */
  874. d30 1
  875. a30 1
  876. #endif /* SMTP */
  877. d33 1
  878. a33 1
  879. #ifdef SMTP
  880. d100 1
  881. a100 1
  882. # define EX_QUIT    22        /* special code for QUIT command */
  883. d491 1
  884. a491 1
  885. #  ifdef LOG
  886. d497 1
  887. a497 1
  888. #  endif /* LOG */
  889. a502 1
  890. # ifdef LOG
  891. a503 1
  892. # endif /* LOG */
  893. d675 1
  894. a675 1
  895. #endif SMTP
  896. @
  897.  
  898.  
  899. 5.28.0.4
  900. log
  901. @Trivial fix from neil Rickert (rickert@@cs.niu.edu).
  902. @
  903. text
  904. @d260 1
  905. @
  906.  
  907.  
  908. 5.28.0.5
  909. log
  910. @Commented out tokens following #endif statements.  Fixed forward declaration
  911. of skipword.  Deleted un-used assignment.
  912. @
  913. text
  914. @d30 1
  915. a30 1
  916. # endif /* SMTP */
  917. a98 1
  918. char     *skipword();
  919. d109 1
  920. d188 1
  921. a511 1
  922.         /* NOTREACHED */
  923. d676 1
  924. a676 1
  925. #endif /* SMTP */
  926. @
  927.  
  928.  
  929. 5.28.0.6
  930. log
  931. @Deleted #include <sys/types.h> as it's already included via sendmail.h from
  932. useful.h.  #include "sendmail.h" relocated to top of #include list.
  933. @
  934. text
  935. @a20 1
  936. #include "sendmail.h"
  937. d23 1
  938. @
  939.  
  940.  
  941. 5.28.0.7
  942. log
  943. @Added static keyword to declaration of help() and runinchild().
  944. @
  945. text
  946. @a122 1
  947.     static help(), runinchild();
  948. a575 1
  949. static
  950. a632 1
  951. static
  952. @
  953.  
  954.  
  955. 5.28.0.8
  956. log
  957. @ANSIfied.
  958. @
  959. text
  960. @a34 10
  961. #ifdef __STDC__
  962. static char * skipword(char *, const char *);
  963. static void help(char *);
  964. static runinchild(const char *);
  965. #else /* !__STDC__ */
  966. static char * skipword();
  967. static void help();
  968. static runinchild();
  969. #endif /* __STDC__ */
  970.  
  971. d99 1
  972. a102 1
  973. void
  974. d119 2
  975. d122 2
  976. d533 1
  977. a533 1
  978.     const char *w;
  979. d577 1
  980. a577 1
  981. static void
  982. d637 1
  983. a637 1
  984.     const char *label;
  985. a643 2
  986.         if (childpid > 0 && tTd(4, 2))
  987.             printf("runinchild: forking (pid = %d)\n", childpid);
  988. @
  989.  
  990.  
  991. 5.28.0.9
  992. log
  993. @HELP with no arguments would sometimes cause a core dump.  Depending
  994. on the compiler, constant strings are placed in read-only memory.
  995. HELP with no arguments attempts to makelower() a constant string in
  996. place.  The fix is to use newstr()/free() within the help() routine.
  997. Reported by Steve Davies  srd@@peora.sdc.ccur.com.
  998. @
  999. text
  1000. @a599 1
  1001.     topic = newstr(topic);
  1002. a624 1
  1003.     free(topic);
  1004. @
  1005.  
  1006.  
  1007. 5.28.0.10
  1008. log
  1009. @Include <sys/signal.h>, not <signal.h>.
  1010. @
  1011. text
  1012. @d23 1
  1013. a23 1
  1014. #include <sys/signal.h>
  1015. @
  1016.  
  1017.  
  1018. 5.28.0.11
  1019. log
  1020. @Added RCS ID string
  1021. @
  1022. text
  1023. @a27 1
  1024. static char  rcsid[] = "@@(#)$Id$ (with SMTP)";
  1025. a29 1
  1026. static char  rcsid[] = "@@(#)$Id$ (without SMTP)";
  1027. @
  1028.  
  1029.  
  1030. 5.28.0.12
  1031. log
  1032. @System 5 and general improvement patches contributed by Bruce Lilly
  1033. (bruce%balilly@@broadcast.sony.com).
  1034. @
  1035. text
  1036. @d27 2
  1037. a28 2
  1038. static char sccsid[] = "@@(#)srvrsmtp.c    5.28 (Berkeley) 6/1/90 (with SMTP)    %I% local";
  1039. static char  rcsid[] = "@@(#)$Id: srvrsmtp.c,v 5.28.0.11 1991/04/05 14:55:15 paul Exp paul $ (with SMTP)";
  1040. d30 2
  1041. a31 2
  1042. static char sccsid[] = "@@(#)srvrsmtp.c    5.28 (Berkeley) 6/1/90 (without SMTP)    %I% local";
  1043. static char  rcsid[] = "@@(#)$Id: srvrsmtp.c,v 5.28.0.11 1991/04/05 14:55:15 paul Exp paul $ (without SMTP)";
  1044. d40 1
  1045. a40 1
  1046. static int runinchild(const char *);
  1047. d44 1
  1048. a44 1
  1049. static int runinchild();
  1050. d129 1
  1051. d154 1
  1052. a154 2
  1053.     if (batched && la > RefuseLA)
  1054.     {
  1055. d159 1
  1056. a159 1
  1057.     message("220", "%s", inp);
  1058. d373 1
  1059. a373 2
  1060.             if (!batched)
  1061.             {
  1062. d619 1
  1063. a619 1
  1064.             message("214-", "%s", p);
  1065. d645 1
  1066. a645 1
  1067. static int
  1068. @
  1069.  
  1070.  
  1071. 5.28.0.13
  1072. log
  1073. @Save given host name if it differs from the looked up host name.
  1074. @
  1075. text
  1076. @d28 1
  1077. a28 1
  1078. static char  rcsid[] = "@@(#)$Id: srvrsmtp.c,v 5.28.0.16 1991/06/03 22:57:41 paul Exp paul $ (with SMTP)";
  1079. d31 1
  1080. a31 1
  1081. static char  rcsid[] = "@@(#)$Id: srvrsmtp.c,v 5.28.0.16 1991/06/03 22:57:41 paul Exp paul $ (without SMTP)";
  1082. d125 1
  1083. a125 1
  1084.     char *sendinghost = NULL;
  1085. a129 1
  1086.     char *q;
  1087. d161 1
  1088. a161 1
  1089.     DeclHostName = NULL;
  1090. d220 2
  1091. a221 2
  1092.             (void) strcpy(hostbuf, p);
  1093.             (void) maphostname(hostbuf, sizeof(hostbuf));
  1094. d234 1
  1095. a234 1
  1096.                 DeclHostName = newstr(hostbuf);
  1097. a249 3
  1098.             {
  1099.                 if (sendinghost)
  1100.                     free(sendinghost);
  1101. a250 1
  1102.             }
  1103. d521 1
  1104. a522 1
  1105.     /* NOTREACHED */
  1106. a685 1
  1107. #if !defined(DBM_AUTOBUILD) || ( !defined(NDBM) && !defined(OTHERDBM) )
  1108. a687 1
  1109. #endif /* !DBM_AUTOBUILD || (!NDBM && !OTHERDBM) */
  1110. @
  1111.  
  1112.  
  1113. 5.28.0.14
  1114. log
  1115. @Fix use of RealHostName.
  1116. @
  1117. text
  1118. @d28 1
  1119. a28 1
  1120. static char  rcsid[] = "@@(#)$Id: srvrsmtp.c,v 5.28.0.13 1991/06/06 19:50:49 paul Exp paul $ (with SMTP)";
  1121. d31 1
  1122. a31 1
  1123. static char  rcsid[] = "@@(#)$Id: srvrsmtp.c,v 5.28.0.13 1991/06/06 19:50:49 paul Exp paul $ (without SMTP)";
  1124. d254 1
  1125. a254 1
  1126.                 sendinghost = newstr(RealHostName);
  1127. @
  1128.  
  1129.  
  1130. 5.28.0.15
  1131. log
  1132. @Changes for setjmp/longjmp optimization.
  1133. @
  1134. text
  1135. @d27 2
  1136. a28 2
  1137. static char sccsid[] = "@@(#)srvrsmtp.c    5.28 (Berkeley) 6/1/90 (with SMTP)";
  1138. static char  rcsid[] = "@@(#)$Id: srvrsmtp.c,v 5.28.0.14 1991/06/13 20:18:34 paul Exp paul $ (with SMTP)";
  1139. d30 2
  1140. a31 2
  1141. static char sccsid[] = "@@(#)srvrsmtp.c    5.28 (Berkeley) 6/1/90 (without SMTP)";
  1142. static char  rcsid[] = "@@(#)$Id: srvrsmtp.c,v 5.28.0.14 1991/06/13 20:18:34 paul Exp paul $ (without SMTP)";
  1143. a113 4
  1144. static bool hasmail;            /* mail command received */
  1145. static char *sendinghost;
  1146. static char *ptr;
  1147.  
  1148. d118 1
  1149. d122 1
  1150. d125 1
  1151. d129 2
  1152. a133 1
  1153.     sendinghost = NULL;
  1154. d177 1
  1155. a177 1
  1156.         ptr = sfgets(inp, sizeof inp, InChannel);
  1157. d180 1
  1158. a180 1
  1159.         if (ptr == NULL)
  1160. d196 1
  1161. a196 1
  1162.         for (ptr = inp; isspace(*ptr); ptr++)
  1163. d198 2
  1164. a199 2
  1165.         for (cmd = cmdbuf; *ptr != '\0' && !isspace(*ptr); )
  1166.             *cmd++ = *ptr++;
  1167. d203 2
  1168. a204 2
  1169.         while (isspace(*ptr))
  1170.             ptr++;
  1171. d221 3
  1172. a223 1
  1173.             if (!strcmp(ptr, MyHostName))
  1174. d232 1
  1175. a232 1
  1176.             if (RealHostName != NULL && strcasecmp(ptr, RealHostName))
  1177. d234 1
  1178. a234 3
  1179.                 char hostbuf[MAXNAME];
  1180.  
  1181.                 (void) sprintf(hostbuf, "%s (%s)", ptr, RealHostName);
  1182. d237 1
  1183. a237 1
  1184.                     RealHostName, ptr);
  1185. d241 2
  1186. a242 2
  1187.                 sendinghost = newstr(ptr);
  1188.                 message("250", "Hello %s, pleased to meet you", ptr);
  1189. d280 2
  1190. a281 2
  1191.             ptr = skipword(ptr, "from");
  1192.             if (ptr == NULL)
  1193. d283 1
  1194. a283 1
  1195.             setsender(ptr);
  1196. d304 2
  1197. a305 2
  1198.             ptr = skipword(ptr, "to");
  1199.             if (ptr == NULL)
  1200. d307 1
  1201. a307 1
  1202.             a = parseaddr(ptr, (ADDRESS *) NULL, 1, '\0');
  1203. d316 1
  1204. a316 1
  1205.             CurEnv->e_to = ptr;
  1206. d421 1
  1207. a421 1
  1208.             sendtolist(ptr, (ADDRESS *) NULL, &vrfyqueue);
  1209. d457 3
  1210. a459 3
  1211.             if (*ptr == '\0')
  1212.                 ptr = "SMTP";
  1213.             help(ptr);
  1214. d484 1
  1215. a484 1
  1216.             (void) strncpy(TickArg, ptr, 20-1);
  1217. d496 1
  1218. a496 1
  1219.             tTflag(ptr);
  1220. @
  1221.